#include <stdbool.h>
#include "clib_memory_allocator.h"
#include "clib_memory_allocator_standard.h"

static struct clib_memory_allocator *global_allocators[CLIB_ALLOCATOR_TYPE_NUM];

int clib_memory_allocator_init(enum clib_allocator_type type) {
    if (clib_memory_allocator_standard_init() != CLIB_RES_OK) {
        return CLIB_RES_OTHER_ERROR;
    }
    global_allocators[CLIB_ALLOCATOR_TYPE_STANDARD] = clib_memory_allocator_standard_get();
    global_allocators[CLIB_ALLOCATOR_TYPE_DEFAULT] = global_allocators[type];
    return CLIB_RES_OK;
}

void *clib_memory_allocator_malloc_default(clib_uint64_t size) {
    return clib_memory_allocator_malloc(size, CLIB_ALLOCATOR_TYPE_DEFAULT);
}

void *clib_memory_allocator_re_alloc_default(void *data, clib_uint64_t size) {
    return clib_memory_allocator_re_alloc(data, size, CLIB_ALLOCATOR_TYPE_DEFAULT);
}

void clib_memory_allocator_free_default(void *data) {
    clib_memory_allocator_free(data, CLIB_ALLOCATOR_TYPE_DEFAULT);
}

void clib_memory_allocator_mem_copy_default(void *target, void *src, size_t length) {
    clib_memory_allocator_mem_copy(target, src, length, CLIB_ALLOCATOR_TYPE_DEFAULT);
}

void *clib_memory_allocator_malloc(clib_uint64_t size, enum clib_allocator_type type) {
    void *data = global_allocators[type]->malloc(size);
    memset(data, 0, size);
    return data;
}

void *clib_memory_allocator_re_alloc(void *data, clib_uint64_t size, enum clib_allocator_type type) {
    return global_allocators[type]->re_alloc(data, size);
}

void clib_memory_allocator_free(void *data, enum clib_allocator_type type) {
    global_allocators[type]->free(data);
}

void clib_memory_allocator_mem_copy(void *target, void *src, size_t length, enum clib_allocator_type type) {
    global_allocators[type]->mem_copy(target, src, length);
}